package com.extremelylargepackage.entity;

import java.io.IOException;

import org.xml.sax.SAXException;

import java.util.Map;

import com.extremelylargepackage.GameResources;
import com.extremelylargepackage.sprite.AbstractSprite;
import com.extremelylargepackage.sprite.AnimationParser;
import com.extremelylargepackage.sprite.MalformedAnimationException;

import android.graphics.Canvas;

public class Player extends Character 
{
	private final float DRAG_OFFSET_Y = (float) (.01 * GameResources.SCREEN_HEIGHT);
	private final float DEFAULT_SPEED = GameResources.SCREEN_WIDTH;
	private Shield _shield;
	private Projectile _special;

	public Player(AbstractSprite sprite, float x, float y)
	{
		super();
		_sprite = sprite;
		_locX = x;
		_locY = y;
		_weapon = GameResources.getWeapon("lasergun1");
		_weapon._owner = this;
		_speed = DEFAULT_SPEED;
		_health = _maxHealth = 100;
		_shield = new Shield(this);
		_special = new Nuke(this);
		try {
			_explosionAnim = AnimationParser.parseAnimation("explosion1");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedAnimationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void draw(Canvas c) 
	{
		_special.draw(c);
		super.draw(c);
		if(_shield.isVisible() && _status == Status.alive)
			_shield.draw(c);
	}
	
	public void setDestination(float x, float y)
	{
		//Dragging should be from bottom middle of the ship
		//The coordinates need to be top left however
		//This converts that.
		x = x - (_sprite.getWidth() / 2);
		y = y -  _sprite.getHeight() - DRAG_OFFSET_Y;
		_dirY = y - _locY;
		_dirX = x - _locX;
	}

	@Override
	public void onCollision(Entity e) 
	{
		if(!_shield.isInvincible())
		{
			if(e instanceof Projectile && e._status == Status.alive)
			{
				_health -= ((Projectile)e)._damage;
				_shield.activate(false);
			}
			else if(e instanceof Enemy)
			{
				Enemy enemy = (Enemy) e;
				_health -= enemy.getCollisionDamage();
				_shield.activate(false);
			}
		}
	}

	@Override
	public void updateState(long time) 
	{
		super.updateState(time);
		_special.updateState(time);
		move(time);
		_shield.updateState(time);
		if(_special instanceof Nuke)
		{
			if(!_shield.isInvincible() && _special.getStatus() == Status.alive && ((Nuke)_special).isExploding())
				_shield.activate(true);
			else if(_shield.isInvincible() && _special.getStatus() == Status.dead)
				_shield.activate(false);
		}
	}
	
	public void fireSpecialWeapon()
	{
		_special.fire();
	}
	
	public Projectile getSpecialProjectile()
	{
		return _special;
	}

	/**
	 * Generates a map of values representing the state of the player. Ex { (health, 100), (x, 100), (y, 250) }
	 * @return state
	 */
	@Override
	public Map<String, Object> getState() {
		Map<String, Object> res = super.getState();

		// Only player-specific property is shield -- not needed?

		return res;
	}
}
